﻿using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace Narwhunderful.Aphelia.Framework.Graphics
{

    public class DrawingContext2D
    {

        static GraphicsDevice _graphicsDevice;

        static Texture2D _pixelTexture = null;
        public Texture2D PixelTexture
        {
            get
            {
                return _pixelTexture;
            }
        }

        internal const int CircleTextureRadius = 512;
        internal static Vector2 CircleTextureRadiusVector = new Vector2(CircleTextureRadius, CircleTextureRadius);

        static Texture2D _circleTexture = null;
        public Texture2D CircleTexture
        {
            get
            {
                return _circleTexture;
            }
        }

        public DrawingContext2D(GraphicsDevice graphicsDevice)
        {
            _graphicsDevice = graphicsDevice;
            if (_pixelTexture == null) _pixelTexture = DrawingHelper.CreatePixelTexture(graphicsDevice);
            if (_circleTexture == null) _circleTexture = DrawingHelper.CreateCircleTexture(graphicsDevice, CircleTextureRadius, 0, 1, 1, Color.White, Color.White);
        }

        public void DrawPixel(SpriteBatch spriteBatch, Vector2 point, Color color)
        {
            spriteBatch.Draw(_pixelTexture, point, color);
        }

        public void DrawLine(SpriteBatch spriteBatch, Vector2 point, float length, float angle, Color color, float thickness)
        {
            spriteBatch.Draw(_pixelTexture, point, null, color, angle, Vector2.Zero, new Vector2(length, thickness), SpriteEffects.None, 0);
        }

        public void DrawLine(SpriteBatch spriteBatch, Vector2 point1, Vector2 point2, Color color, float thickness)
        {
            DrawLine(spriteBatch, point1, Vector2.Distance(point1, point2), (float)Math.Atan2(point2.Y - point1.Y, point2.X - point1.X), color, thickness);
        }

        public void DrawRectangle(SpriteBatch spriteBatch, Rectangle rectangle, Color color, float thickness)
        {
            DrawLine(spriteBatch, new Vector2(rectangle.X, rectangle.Y), new Vector2(rectangle.Right, rectangle.Y), color, thickness);
            DrawLine(spriteBatch, new Vector2(rectangle.Right, rectangle.Y), new Vector2(rectangle.Right, rectangle.Bottom), color, thickness);
            DrawLine(spriteBatch, new Vector2(rectangle.Right, rectangle.Bottom), new Vector2(rectangle.X, rectangle.Bottom), color, thickness);
            DrawLine(spriteBatch, new Vector2(rectangle.X, rectangle.Bottom), new Vector2(rectangle.X, rectangle.Y), color, thickness);
        }

        public void DrawFilledRectangle(SpriteBatch spriteBatch, Rectangle rectangle, Color color)
        {
            spriteBatch.Draw(_pixelTexture, rectangle, color);
        }

        public void DrawPath(SpriteBatch spriteBatch, List<Vector2> points, Color color, float thickness)
        {
            for (int i = 0; i < points.Count - 1; i++)
            {
                DrawLine(spriteBatch, points[i], points[i + 1], color, thickness);
            }
        }

        public void DrawPath(SpriteBatch spriteBatch, Vector2 position, List<Vector2> points, Color color, float thickness)
        {
            for (int i = 0; i < points.Count - 1; i++)
            {
                DrawLine(spriteBatch, points[i] + position, points[i + 1] + position, color, thickness);
            }
        }

        public void DrawPolygon(SpriteBatch spriteBatch, List<Vector2> points, Color color, float thickness)
        {
            DrawPath(spriteBatch, points, color, thickness);
            DrawLine(spriteBatch, points[points.Count - 1], points[0], color, thickness);
        }

        public void DrawPolygon(SpriteBatch spriteBatch, Vector2 position, List<Vector2> points, Color color, float thickness)
        {
            DrawPath(spriteBatch, position, points, color, thickness);
            DrawLine(spriteBatch, points[points.Count - 1] + position, points[0] + position, color, thickness);
        }

        public void DrawCircle(SpriteBatch spriteBatch, Vector2 point, float radius, int sides, Color color, float thickness)
        {
            DrawPolygon(spriteBatch, point, DrawingHelper.CreateCircle(radius, sides), color, thickness);
        }
        public void DrawFilledCircle(SpriteBatch spriteBatch, Vector2 point, float radius, Color color)
        {
            spriteBatch.Draw(_circleTexture, point, null, color, 0, CircleTextureRadiusVector, radius / CircleTextureRadius, SpriteEffects.None, 0);
        }

        public void DrawArc(SpriteBatch spriteBatch, Vector2 point, float radius, int sides, float startingAngle, float endingAngle, Color color, float thickness)
        {
            DrawPath(spriteBatch, point, DrawingHelper.CreateArc(radius, sides, startingAngle, endingAngle), color, thickness);
        }

    }
}
